package com.xqkj.commons.virtualdb.service.functions;

import com.xqkj.commons.constant.VirtualDbCommonConstants;
import com.xqkj.commons.utils.Assert;
import com.xqkj.commons.utils.BeanReflectUtils;
import com.xqkj.commons.virtualdb.model.*;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.MapUtils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;

/**
 * @author lwt<br>
 * @description <br>
 * @date 2020/1/15
 */
public class LockInfoGetter<P> implements Function<ParametersWrappedModel<P>,VirtualDbLockInfoModel> {
    @Override
    public VirtualDbLockInfoModel apply(ParametersWrappedModel<P> parametersWrappedModel) {
        VirtualDbLockInfoModel virtualDbLockInfoModel=new VirtualDbLockInfoModel();
        virtualDbLockInfoModel.setTenantId(parametersWrappedModel.getTenantId());
        virtualDbLockInfoModel.setTenantExtCode(parametersWrappedModel.getTenantExtCode());
        //
        VirtualDbAttributeIdxConfigModel attributeIdxConfig=parametersWrappedModel.getAttributeIdxConfig();
        //没有配置索引信息，直接返回默认值
        if(attributeIdxConfig==null ||
            (CollectionUtils.isEmpty(attributeIdxConfig.getUidxModelFiledNameList())
            && CollectionUtils.isEmpty(attributeIdxConfig.getConfigValueList()))){
            return virtualDbLockInfoModel;
        }
        P model=parametersWrappedModel.getParameter();
        //位于主模型的索引信息
        if(model!=null && CollectionUtils.isNotEmpty(attributeIdxConfig.getUidxModelFiledNameList())){
            Map<String,Object> mainIdxFieldValueMap=new HashMap<>();
            StringBuilder idxValueSb=new StringBuilder();
            idxValueSb.append(attributeIdxConfig.getConfigCode()).append("_")
                    .append(parametersWrappedModel.getTenantId()).append("_")
                    .append(parametersWrappedModel.getTenantExtCode());
            attributeIdxConfig.getUidxModelFiledNameList().forEach(item-> {
                Object result=BeanReflectUtils.invokeGetMethodByFiledName(item,model);
                Assert.isNotNull(result,"字段"+item+"不可以为null");
                idxValueSb.append("_").append(String.valueOf(result));
                mainIdxFieldValueMap.put(item,result);
            });
            virtualDbLockInfoModel.setMainIdxFieldValueMap(mainIdxFieldValueMap);
            virtualDbLockInfoModel.setMainIdxCode(attributeIdxConfig.getConfigCode());
            virtualDbLockInfoModel.setMainIdxName(attributeIdxConfig.getConfigName());
            virtualDbLockInfoModel.setMainIdxLockKey(idxValueSb.toString());
        }
        //位于模型属性相关索引信息
        Map<String,ModelBasicAttributeSvModel> attributeSvModelMap = parametersWrappedModel.getCodeToAttributeMap();
        if(CollectionUtils.isNotEmpty(attributeIdxConfig.getConfigValueList()) && !MapUtils.isEmpty(attributeSvModelMap)){
            //
            List<VirtualDbAttributeLockInfoModel> attributeLockInfoList=new ArrayList<>();
            //
            attributeIdxConfig.getConfigValueList().forEach(item->{
                if(VirtualDbCommonConstants.ModelAttributeIdx.not_idx==item.getAttributeIdxType()){
                    return;
                }
                ModelBasicAttributeSvModel tmpAttribute = attributeSvModelMap.get(item.getAttributeCode());
                if(tmpAttribute==null){
                    return;
                }
                String key=generateModelAttributeKey(attributeIdxConfig.getConfigCode(),
                        tmpAttribute.getTenantId(),tmpAttribute.getTenantExtCode(),
                        tmpAttribute.getAttributeCode(),tmpAttribute.getAttributeValue());
                VirtualDbAttributeLockInfoModel virtualDbAttributeLockInfo=new VirtualDbAttributeLockInfoModel();
                virtualDbAttributeLockInfo.setAttributeCode(item.getAttributeCode());
                virtualDbAttributeLockInfo.setAttributeName(item.getAttributeName());
                virtualDbAttributeLockInfo.setAttributeValue(tmpAttribute.getAttributeValue());
                virtualDbAttributeLockInfo.setLockKey(key);
                attributeLockInfoList.add(virtualDbAttributeLockInfo);
            });
            virtualDbLockInfoModel.setAttributeLockInfolList(attributeLockInfoList);
        }
        virtualDbLockInfoModel.setNeedLock(true);
        return virtualDbLockInfoModel;
    }

    private String generateModelAttributeKey(String parentConfigCode,Long tenantId,String tenantExtCode,
                                             String attributeCode,String attributeValue){
        StringBuilder stringBuilder=new StringBuilder();
        stringBuilder.append(parentConfigCode).append("_").append(tenantId).append("_")
                .append(tenantExtCode).append("_").append(attributeCode).append("_")
                .append(attributeValue);
        return stringBuilder.toString();
    }


}
